package com.gzx.plugin.tjzy.modular.sms.api.strategy.ll.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.gzx.plugin.tjzy.modular.founds.service.GzxFoundsFlowService;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.SMSStrategy;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.common.dto.CommonSmsSendReqDto;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.common.dto.CommonSmsSendRespDto;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.ll.dto.SMSLLReceiptRespDto;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.ll.dto.SMSLLReplyRespDto;
import com.gzx.plugin.tjzy.modular.sms.api.strategy.ll.dto.SMSLLSendRespDto;
import com.gzx.plugin.tjzy.modular.sms.api.template.SmsTemplateMethod;
import com.gzx.plugin.tjzy.modular.sms.batch.consts.SMSLLConstant;
import com.gzx.plugin.tjzy.modular.sms.batch.enums.GzxSmsSendStatusEnum;
import com.gzx.plugin.tjzy.modular.sms.batch.service.GzxSmsDbService;
import com.gzx.plugin.tjzy.modular.sms.receipt.consts.GzxSendStatusMappingConstant;
import com.gzx.plugin.tjzy.modular.sms.receipt.entity.GzxSmsReceipt;
import com.gzx.plugin.tjzy.modular.sms.receipt.service.GzxSmsReceiptService;
import com.gzx.plugin.tjzy.modular.sms.record.service.GzxSmsRecordService;
import com.gzx.plugin.tjzy.modular.sms.reply.entity.GzxSmsReply;
import com.gzx.plugin.tjzy.modular.sms.reply.service.GzxSmsReplyService;
import com.gzx.plugin.tjzy.modular.supplier.consts.GzxSupplierConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import vip.xiaonuo.common.util.CommonCryptogramUtil;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.CommonHttpUtil;

import java.util.*;

/**
 * @author zjt
 * @description
 * @date 2025/7/21 15:28
 */
@Slf4j
@Service
@DS("sms")
public class SMSLLStrategyImpl extends SmsTemplateMethod implements SMSStrategy {

    @Value("${sms.ll.url}")
    private String url;

    @Value("${sms.ll.balanceUrl}")
    private String balanceUrl;

    @Value("${sms.ll.mchId}")
    private String mchId;

    @Value("${sms.ll.appId}")
    private String appId;

    @Value("${sms.ll.appKey}")
    private String appKey;

    private static final String MCH_ID = "MchId";
    private static final String APP_ID = "AppId";
    private static final String VERSION = "Version";
    private static final String SIGN_TYPE = "SignType";
    private static final String SIGNATURE = "Signature";
    private static final String TIMESTAMP = "TimeStamp";

    public SMSLLStrategyImpl(GzxSmsDbService smsDbService, GzxSmsRecordService smsRecordService, GzxSmsReceiptService smsReceiptService, GzxFoundsFlowService foundsFlowService, GzxSmsReplyService smsReplyService) {
        super(smsDbService, smsRecordService, smsReceiptService, foundsFlowService, smsReplyService);
    }

    /**
     * 获取当前供应商
     *
     * @return
     */
    @Override
    public String getCurrentSupplierCode() {
        return GzxSupplierConstant.LL;
    }

    /**
     * 获取短信签名
     *
     * @param city
     * @return
     */
    @Override
    protected String getSignName(String city) {
        if ("天津".equals(city)) {
            return "【天津普惠金融调解中心】";
        }
        if ("盐城".equals(city)) {
            return "【盐城市盐南高新区金和金融调解中心】";
        }
        return "";
    }

    /**
     * 开始发送短信
     *
     * @param commonSmsSendReqDtoList 发送短信的集合
     * @return
     */
    @Override
    protected List<CommonSmsSendRespDto> startSend(List<CommonSmsSendReqDto> commonSmsSendReqDtoList) {
        try {
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put(MCH_ID, mchId);
            reqBody.put(APP_ID, appId);
            reqBody.put(VERSION, "1.2.0");
            reqBody.put("Type", "2");
            String signName = getSignName(commonSmsSendReqDtoList.getFirst().getSignCity());
            reqBody.put("SignName", signName);
            reqBody.put("SessionContextSet", "{%变量%}");
            List<String[]> resultArray = commonSmsSendReqDtoList.stream().map(obj -> new String[]{obj.getPhone(), modifySmsSignature(obj.getSignCity(), obj.getMessage())}).toList();
            reqBody.put("ContextParamSet", resultArray);
            long timeStamp = System.currentTimeMillis();
            reqBody.put(TIMESTAMP, timeStamp);
            reqBody.put(SIGN_TYPE, "MD5");
            String signature = APP_ID + "=" +
                    appId +
                    "&" + MCH_ID + "=" +
                    mchId +
                    "&SignName=" + signName +
                    "&" + SIGN_TYPE + "=MD5" +
                    "&" + TIMESTAMP + "=" +
                    timeStamp +
                    "&Type=2&" + VERSION + "=1.2.0&key=" +
                    appKey;
            reqBody.put(SIGNATURE, CommonCryptogramUtil.doMd5(signature).toUpperCase());
            String respBody = CommonHttpUtil.post(url + SMSLLConstant.ONE_ONE, null, JSON.toJSONString(reqBody), "联麓短信发送");
            SMSLLSendRespDto smsllSendRespDto = JSONObject.parseObject(respBody, SMSLLSendRespDto.class);
            if (smsllSendRespDto != null && "00".equals(smsllSendRespDto.getStatus())) {
                List<CommonSmsSendRespDto> smsSendRespBoList = new ArrayList<>();
                commonSmsSendReqDtoList.forEach(s -> smsSendRespBoList.add(new CommonSmsSendRespDto(s.getPhone(), smsllSendRespDto.getTaskId(), 0)));
                return smsSendRespBoList;
            }
            return defaultResp(commonSmsSendReqDtoList, GzxSmsSendStatusEnum.FAIL.getCode(), GzxSupplierConstant.LL);
        } catch (Exception e) {
            log.error("调用联麓短信接口出现异常", e);
            return defaultResp(commonSmsSendReqDtoList, GzxSmsSendStatusEnum.FAIL.getCode(), GzxSupplierConstant.LL);
        }
    }

    /**
     * 同步短信回执
     *
     * @return
     */
    @Override
    protected List<GzxSmsReceipt> startSyncReceipt() {
        try {
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put(MCH_ID, mchId);
            reqBody.put(APP_ID, appId);
            reqBody.put(VERSION, "2.0.0");
            long timeStamp = System.currentTimeMillis();
            reqBody.put(TIMESTAMP, timeStamp);
            reqBody.put(SIGN_TYPE, "MD5");
            String signature = "AppId=" +
                    appId +
                    "&" + MCH_ID + "=" +
                    mchId +
                    "&" + SIGN_TYPE + "=MD5" +
                    "&" + TIMESTAMP + "=" +
                    timeStamp +
                    "&" + VERSION + "=2.0.0&key=" +
                    appKey;
            reqBody.put(SIGNATURE, CommonCryptogramUtil.doMd5(signature).toUpperCase());
            String resp = CommonHttpUtil.post(url + SMSLLConstant.RECEIPT, null, JSON.toJSONString(reqBody), "联麓短信状态查询");
            SMSLLReceiptRespDto smsllReceiptRespDto = JSONObject.parseObject(resp, SMSLLReceiptRespDto.class);
            List<GzxSmsReceipt> smsReceiptList = new ArrayList<>();
            if (smsllReceiptRespDto != null && "00".equals(smsllReceiptRespDto.getStatus()) && CollectionUtil.isNotEmpty(smsllReceiptRespDto.getData())) {
                List<SMSLLReceiptRespDto.LLReceiptDetail> resultList = expandByCount(smsllReceiptRespDto.getData());
                String currentDate = CommonDateUtil.getCurrentTimeStr();
                for (SMSLLReceiptRespDto.LLReceiptDetail llReceiptDetail : resultList) {
                    GzxSmsReceipt smsReceipt = new GzxSmsReceipt();
                    smsReceipt.setSupplierCode(GzxSupplierConstant.LL);
                    smsReceipt.setFlagType(1);
                    smsReceipt.setPhone(llReceiptDetail.getPhone());
                    smsReceipt.setMsgId(llReceiptDetail.getTaskId());
                    smsReceipt.setSendTime(CommonDateUtil.formatTimestamp(llReceiptDetail.getRespTime()));
                    smsReceipt.setResultCode(llReceiptDetail.getRespCode());
                    smsReceipt.setMappingStatus(GzxSupplierConstant.LL_SUCCESS.equals(llReceiptDetail.getRespCode()) ? GzxSendStatusMappingConstant.SUCCESS : GzxSendStatusMappingConstant.FAIL);
                    smsReceipt.setAllDetail(JSON.toJSONString(llReceiptDetail));
                    smsReceipt.setCreateTime(currentDate);
                    smsReceiptList.add(smsReceipt);
                }
            }
            return smsReceiptList;
        } catch (Exception e) {
            log.error("调用联麓查询接口出现异常", e);
            return Collections.emptyList();
        }
    }

    /**
     * 开始同步短信回复
     *
     * @return
     */
    @Override
    protected List<GzxSmsReply> startSyncReply() {
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put(MCH_ID, mchId);
        reqBody.put(APP_ID, appId);
        reqBody.put(VERSION, "1.1.0");
        long timeStamp = System.currentTimeMillis();
        reqBody.put(TIMESTAMP, timeStamp);
        reqBody.put(SIGN_TYPE, "MD5");
        String today = CommonDateUtil.getYearMonthDateStr();
        reqBody.put("Date", today);
        String signature = "AppId=" +
                appId +
                "&Date=" + today +
                "&" + MCH_ID + "=" +
                mchId +
                "&" + SIGN_TYPE + "=MD5" +
                "&" + TIMESTAMP + "=" +
                timeStamp +
                "&" + VERSION + "=1.1.0" +
                "&key=" +
                appKey;
        try {
            reqBody.put(SIGNATURE, CommonCryptogramUtil.doMd5(signature).toUpperCase());
            List<GzxSmsReply> smsReplyList = new ArrayList<>();
            String resp = CommonHttpUtil.post(url + SMSLLConstant.REPLY, null, JSON.toJSONString(reqBody), "联麓短信回复查询");
            SMSLLReplyRespDto smsllReplyRespDto = JSONObject.parseObject(resp, SMSLLReplyRespDto.class);
            if (smsllReplyRespDto != null && "00".equals(smsllReplyRespDto.getStatus()) && CollectionUtil.isNotEmpty(smsllReplyRespDto.getData())) {
                for (SMSLLReplyRespDto.LLReplyDetail llReplyDetail : smsllReplyRespDto.getData()) {
                    llReplyDetail.setRespContent(StringUtils.deleteWhitespace(llReplyDetail.getRespContent()).replaceAll("[\\x00-\\x1F]", ""));
                    GzxSmsReply smsReply = new GzxSmsReply();
                    smsReply.setSupplierCode(GzxSupplierConstant.LL);
                    smsReply.setMsgId(llReplyDetail.getTaskId());
                    smsReply.setPhone(llReplyDetail.getPhone());
                    smsReply.setReplyContent(llReplyDetail.getRespContent());
                    smsReply.setReplyTime(llReplyDetail.getRespTime());
                    smsReply.setReplyDetail(JSON.toJSONString(llReplyDetail));
                    smsReplyList.add(smsReply);
                }
            }
            return smsReplyList;
        } catch (Exception e) {
            log.error("调用联麓短信回复查询接口出现异常", e);
            return List.of();
        }
    }

    @Override
    protected boolean isSuccess(String resultCode) {
        return GzxSupplierConstant.LL_SUCCESS.equals(resultCode);
    }

    /**
     * 是否需要根据短信ID分组
     *
     * @return
     */
    @Override
    protected boolean isMsgIdGroup() {
        return true;
    }

    private List<SMSLLReceiptRespDto.LLReceiptDetail> expandByCount(List<SMSLLReceiptRespDto.LLReceiptDetail> originalList) {
        List<SMSLLReceiptRespDto.LLReceiptDetail> expandedList = new ArrayList<>();
        for (SMSLLReceiptRespDto.LLReceiptDetail item : originalList) {
            for (int i = 0; i < item.getCount(); i++) {
                SMSLLReceiptRespDto.LLReceiptDetail copy = new SMSLLReceiptRespDto.LLReceiptDetail();
                BeanUtils.copyProperties(item, copy);
                expandedList.add(copy);
            }
        }
        return expandedList;
    }
}
